﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KylinORM.CQRS.Publisher;
using KylinORM.CQRS.Subscriber;

namespace KylinORM.Mapper
{
    /// <summary>
    /// 支持事件的实体映射器接口
    /// </summary>
    public interface IAspectMapper<T> : ISimpleMapper<T> where T : new()
    {
        /// <summary>
        /// 注册命令的处理程序
        /// </summary>
        /// <param name="messageName">命令名称</param>
        /// <param name="messageHandler">命令处理程序</param>
        void On(string messageName, Action<IMessage> messageHandler);
        /// <summary>
        /// 将命令发送到已注册的处理程序
        /// </summary>
        /// <param name="message">命令对象</param>
        void Send(IMessage message);

        /// <summary>
        /// 在实体操作执行前调用指定委托
        /// </summary>
        /// <param name="eventName">事件类型，MapperEvent.EntityCreate/Update/Delete</param>
        /// <param name="eventHandler">事件委托</param>
        /// <returns></returns>
        AspectMapper<T> Before(MapperEvent eventName, Action<BeforeSubmitEvent> eventHandler);
        /// <summary>
        /// 在实体操作完成后调用指定委托
        /// </summary>
        /// <param name="eventName">事件类型，MapperEvent.EntityCreate/Update/Delete</param>
        /// <param name="eventHandler">事件委托</param>
        /// <returns></returns>
        AspectMapper<T> AfterReturning(MapperEvent eventName, Action<AfterReturningEvent> eventHandler);
        /// <summary>
        /// 在实体操作异常时挂起异常并调用指定委托
        /// </summary>
        /// <param name="eventName">事件类型，MapperEvent.EntityCreate/Update/Delete</param>
        /// <param name="eventHandler">事件委托</param>
        /// <returns></returns>
        AspectMapper<T> AfterThrowing(MapperEvent eventName, Action<AfterThrowingEvent> eventHandler);
        /// <summary>
        /// 在实体操作返回时执行调用委托
        /// </summary>
        /// <param name="eventName">事件类型，MapperEvent.EntityCreate/Update/Delete</param>
        /// <param name="eventHandler">事件委托</param>
        /// <returns></returns>
        AspectMapper<T> AfterFinally(MapperEvent eventName, Action<AfterFinallyEvent> eventHandler);
    }
}
